/***********************************************************************************
 * 文件名： page_num_video.c
 * 版本： 1
 * 说明：
 * 		数字主题的输出动画页面。
 * 修改记录：
 * 	2024/02/29: 初版。 刘言。
***********************************************************************************/
#include "page_num_video.h"
#include "resource.h"
#include "ui_ctrl.h"
#include "../dmu.h"
#include "../app.h"
#include "components/lcd_drivers/lcd.h"
#include "components/lcd_drivers/simple_gui/sgui.h"
#include "components/umi/umi_static.h"
#include "components/battery_manager/battery_manager.h"


/////////////////////// 自定义类型

// 状态
typedef enum _status
{
    ST_NORMAL,      // 常规未输出
    ST_OUTING,      // 正在输出
    ST_SET_WAIT,     // 等待设置（数字闪烁）
    ST_SET_CHANGING     // 正在改变设置功率（按钮按下）
}status_t;

// 页面类
typedef struct _page
{
    // 继承页面基类
    ui_page_base_t Base;    // 必须放在最开始表示继承(实例地址=本结构体实例地址)

    sg_pic_t PicVideo;

    u16 StatusTime;
    u8 PicCount;
    bool HasLoad;       // true: 有负载
    dmu_record_t Record;    // 记录数据
}page_t;


/////////////////////// 内部函数申明

static void TimerIsr(void *user_data);
static void BtnEvent(btn_ev_t e, void *user_data);
static void SwsdEvent(swsd_ev_t e);
static void RhcEvent(rhc_ev_t e);
static void StopSmoke(page_t *this);

/////////////////////// 事件

// 页面事件
static void PageEvent(ui_ev_t *e)
{
    page_t *this = (page_t *)e->Target;

    switch (e->Code)
    {
    case UI_EV_PAGE_LOADED:
        Btn_SetCb(BtnEvent, this);
        SWSD_SetCb(SwsdEvent);
        RHC_SetCallBack(RhcEvent);
        Polsys_SetEntry(&PublicTimer, TimerIsr, this);
        Polsys_SetInterval(&PublicTimer, 100);
        App_ClrIdleTime();
        break;
    case UI_EV_PAGE_UNLOADED:
        Polsys_SetEntry(&PublicTimer, NULL, NULL);
        Btn_SetCb(NULL, NULL);
        SWSD_SetCb(NULL);
        RHC_SetCallBack(NULL);
        break;
    default:
        break;
    }
}

/**
 * 软定时器 100ms
*/
static void TimerIsr(void *user_data)
{
    page_t *this = user_data;

    this->StatusTime++;
    this->PicCount++;
    if(this->PicCount == 25)this->PicCount = 0;
    SgPic_setSource(&this->PicVideo, Pic_T0Video[this->PicCount]);

    if(this->HasLoad == false)
    {
        StopSmoke(this);
        Ui_SwitchToPage(Page_CreatWarn, (void *)UI_WARN_NO_POD);
    }
    else if(this->StatusTime >= 100)    // 一口吸烟时间达到10秒
    {
        
        StopSmoke(this);
        Ui_SwitchToPage(Page_CreatWarn, (void *)UI_WARN_TIMEOUT);
    }
}

static void BtnEvent(btn_ev_t e, void *user_data)
{
    page_t *this = user_data;
    App_ClrIdleTime();
    switch(e)
    {
    // case BTN_EV_DOWN:
    // case BTN_EV_LONG_PRESS:
    // case BTN_EV_LONG_PRESS_REPEAT:
    //     break;
    case BTN_EV_UP:
            StopSmoke(this);
            Ui_SwitchToPage(Page_CreatNumMain, NULL);
        break;
    // case BTN_EV_CLICK_2:
    //     break;
    // case BTN_EV_CLICK_3:
    //     break;
    // case BTN_EV_CLICK_4:
    //     break;
    // case BTN_EV_CLICK_5:
    //     break;
    default: break;
    }
}

static void SwsdEvent(swsd_ev_t e)
{
    page_t *this = (page_t *)Ui_GetNowPage();
    App_ClrIdleTime();
    switch(e)
    {
    case SWSD_EV_TRIG:
        break;
    case SWSD_EV_FREE:
        StopSmoke(this);
        Ui_SwitchToPage(Page_CreatNumMain, NULL);
        break;
    default: break;
    }
}

/**
 * RHC事件
*/
static void RhcEvent(rhc_ev_t e)
{
    page_t *this = (page_t *)Ui_GetNowPage();
    App_ClrIdleTime();
    switch(e)
    {
    case RHC_EV_LOADED:
        RHC_UpdateRes();
        this->HasLoad = true;
        break;
    case RHC_EV_UNLOADED:
        this->HasLoad = false;
        break;
    case RHC_EV_NO_BATTERY:
        StopSmoke(this);//!!!!!!!!!!!!!! 考虑稍后提示
        Ui_SwitchToPage(Page_CreatWarn, (void *)UI_WARN_LOW_BATTERY);
        break;
    case RHC_EV_NO_LOAD:
        this->HasLoad = false;  // 先标记，0.1秒后再提示
        break;
    case RHC_EV_SHORT_OUT:
        StopSmoke(this);//!!!!!!!!!!!!!! 考虑稍后提示
        Ui_SwitchToPage(Page_CreatWarn, (void *)UI_WARN_OVER_LOAD);
        break;
    default: break;
    }
}

///////////////////////////////////// 内部其他函数

static void StopSmoke(page_t *this)
{
    RHC_Stop();
    Dmu_Status.Outing = 0;
    this->Record.LastTime = this->StatusTime;
    this->Record.TripPuffs++;
    this->Record.TotalPuffs++;
    this->Record.TripTime += this->Record.LastTime;
    this->Record.TotalTime += this->Record.LastTime;
    Umi_Write(DMU_RECORD_ADDR, (u8 *)(&this->Record), sizeof(dmu_record_t));
}

/////////////////////// 删除

/**
 * 删除页面。
 * 在这里释放页面占用的所有内存，如果有必要可以清除显示。
*/
static void DeletePage(ui_page_base_t *page)
{
    page_t *this = (page_t *)page;

    free(this);
    // Lcd_Clear(0, 0, LCD_SIZE_X - 1, LCD_SIZE_Y - 1);
}

/////////////////////// 创建


ui_page_base_t * Page_CreatNumVideo(void *param)
{
    page_t *page = malloc(sizeof(page_t));
    memset(page, 0, sizeof(page_t));
    Ui_PageBaseInit((ui_page_base_t *)page);
    Ui_PageSetDeleteFun((ui_page_base_t *)page, DeletePage);
    Ui_PageSetCb((ui_page_base_t *)page, PageEvent);

    // 加载保存的参数
    Umi_Read(DMU_RECORD_ADDR, (u8 *)&page->Record, sizeof(dmu_record_t));
    
    // 获取阻值信息
    if(Dmu_Status.LoadRes[0] > 3000) page->HasLoad = false;
    else page->HasLoad = true;

    // 获取已经输出的时长
    page->StatusTime = (int)param;

    // 加载背景
    // Lcd_Clear(0, 0, LCD_SIZE_X - 1, LCD_SIZE_Y - 1);

    // VIDEO
    SgPic_init(&page->PicVideo);
    SgObj_setPosition(&page->PicVideo, 0, 0);
    SgObj_setSize(&page->PicVideo, PIC_T0_VIDEO_0_SIZE_X, PIC_T0_VIDEO_0_SIZE_Y);
    SgPic_setSource(&page->PicVideo, PIC_T0_VIDEO_0_ADDR);
    

    return (ui_page_base_t *)page;
}




